﻿'Imports System.Data.SqlServerCe

'Friend Class ObjectPersister
'    Public Shared Function GetOne(Of T)(ByVal whereClause As String) As T
'        Return GetOneWorker(Of T)(whereClause, Nothing, Nothing)
'    End Function
'    Public Shared Function GetOne(Of T)(ByVal whereClause As String, ByVal ParamArray parameters() As SqlCeParameter) As T
'        Return GetOneWorker(Of T)(whereClause, Nothing, parameters)
'    End Function
'    Public Shared Function GetOne(Of T)(ByVal whereClause As String, ByVal transactionScope As TransactionScope) As T
'        Return GetOneWorker(Of T)(whereClause, transactionScope, Nothing)
'    End Function
'    Public Shared Function GetOne(Of T)(ByVal whereClause As String, ByVal transactionScope As TransactionScope, ByVal ParamArray parameters() As SqlCeParameter) As T
'        Return GetOneWorker(Of T)(whereClause, transactionScope, parameters)
'    End Function

'    Private Shared Function GetOneWorker(Of T)(ByVal whereClause As String, ByVal transactionScope As TransactionScope, ByVal parameters() As SqlCeParameter) As T
'        Dim clsTypeDef As TypeDefinition = GetTypeDef(GetType(T))

'        Dim sqlCmd As Command = GenerateSelectCommand(clsTypeDef, whereClause, Nothing, transactionScope)
'        If parameters IsNot Nothing AndAlso parameters.Count > 0 Then sqlCmd.AddParameterRange(parameters)

'        If sqlCmd.Transaction Is Nothing Then sqlCmd.Connection.Open()
'        Try
'            Environment.OnDBTraceInfoCommand(sqlCmd)
'            Using dr As SqlCeDataReader = sqlCmd.ExecuteReader
'                If dr.Read Then
'                    Return DRToObject(Of T)(dr, clsTypeDef)
'                Else
'                    Return Nothing
'                End If
'            End Using
'        Finally
'            If sqlCmd.Transaction Is Nothing Then sqlCmd.Connection.Close()
'        End Try
'    End Function

'    Public Shared Function GetAll(Of T)() As Generic.List(Of T)
'        Return GetAllWorker(Of T)(Nothing, Nothing, Nothing, Nothing)
'    End Function

'    Public Shared Function GetAll(Of T)(ByVal parameters() As SqlCeParameter, ByVal whereClause As String) As Generic.List(Of T)
'        Return GetAllWorker(Of T)(whereClause, Nothing, parameters, Nothing)
'    End Function
'    Public Shared Function GetAll(Of T)(ByVal whereClause As String, ByVal transactionScope As TransactionScope, ByVal ParamArray parameters() As SqlCeParameter) As Generic.List(Of T)
'        Return GetAllWorker(Of T)(whereClause, Nothing, parameters, transactionScope)
'    End Function
'    Public Shared Function GetAll(Of T)(ByVal whereClause As String, ByVal ParamArray parameters() As SqlCeParameter) As Generic.List(Of T)
'        Return GetAllWorker(Of T)(whereClause, Nothing, parameters, Nothing)
'    End Function

'    Public Shared Function GetAll(Of T)(ByVal whereClause As String, ByVal orderByClause As String, ByVal ParamArray parameters() As SqlCeParameter) As Generic.List(Of T)
'        Return GetAllWorker(Of T)(whereClause, orderByClause, parameters, Nothing)
'    End Function

'    Private Shared Function GetAllWorker(Of T)(ByVal whereClause As String, ByVal orderByClause As String, ByVal parameters() As SqlCeParameter, ByVal transactionScope As TransactionScope) As Generic.List(Of T)
'        Dim clsTypeDef As TypeDefinition = GetTypeDef(GetType(T))

'        Dim sqlCmd As Command = GenerateSelectCommand(clsTypeDef, whereClause, orderByClause, transactionScope)
'        If parameters IsNot Nothing AndAlso parameters.Count > 0 Then sqlCmd.AddParameterRange(parameters)

'        Dim aRet As New Generic.List(Of T)
'        If sqlCmd.Transaction Is Nothing Then sqlCmd.Connection.Open()
'        Try
'            Environment.OnDBTraceInfoCommand(sqlCmd)
'            Using dr As SqlCeDataReader = sqlCmd.ExecuteReader
'                While dr.Read
'                    aRet.Add(DRToObject(Of T)(dr, clsTypeDef))
'                End While
'            End Using
'        Finally
'            If sqlCmd.Transaction Is Nothing Then sqlCmd.Connection.Close()
'        End Try
'        Return aRet
'    End Function

'    Private Shared Function GenerateSelectCommand(ByVal typeDef As TypeDefinition, ByVal whereClause As String, ByVal orderByClause As String, ByVal transactionScope As TransactionScope) As Command
'        Dim clsSql As New System.Text.StringBuilder(typeDef.SelectSqlStatement)
'        If Not String.IsNullOrEmpty(whereClause) Then
'            clsSql.Append(" WHERE ")
'            clsSql.Append(whereClause)
'        End If
'        If Not String.IsNullOrEmpty(orderByClause) Then
'            clsSql.Append(" ORDER BY ")
'            clsSql.Append(orderByClause)
'        End If

'        If transactionScope IsNot Nothing AndAlso transactionScope.IsNullTransaction Then
'            Return Environment.NewCommand(clsSql.ToString, transactionScope)
'        Else
'            Return Environment.NewCommand(clsSql.ToString)
'        End If
'    End Function

'    Public Shared Sub DefineObject(ByVal type As Type, ByVal tableName As String, ByVal columns() As String)
'        Dim sName As String = type.Name
'        If mTypeDefinitions.ContainsKey(sName) Then Return

'        Dim clsDef As New TypeDefinition
'        clsDef.FieldCount = columns.Count
'        clsDef.Type = type
'        clsDef.TableName = tableName
'        System.Array.Resize(clsDef.ColumnFieldInfos, columns.Count)
'        System.Array.Resize(clsDef.CustomSetHandlers, columns.Count)
'        Dim clsSql As New System.Text.StringBuilder("SELECT ")
'        For i As Integer = 0 To columns.Count - 1
'            Dim sColDef As String = columns(i)
'            Dim sTableColName As String
'            Dim sFieldName As String
'            Dim iPos As Integer = sColDef.IndexOf("/"c)
'            If iPos > 0 Then
'                sTableColName = sColDef.Substring(0, iPos)
'                sFieldName = sColDef.Substring(iPos + 1)
'            Else
'                sTableColName = sColDef
'                sFieldName = sColDef
'            End If

'            If i = 0 Then
'                clsSql.Append("[")
'            Else
'                clsSql.Append(",[")
'            End If
'            clsSql.Append(sTableColName)
'            clsSql.Append("]"c)
'            If sFieldName = "[CUSTOM]" Then
'            Else
'                clsDef.ColumnFieldInfos(i) = type.GetField(sFieldName)
'                If clsDef.ColumnFieldInfos(i) Is Nothing Then
'                    Throw New ArgumentException(String.Format("Field {0} not found on type {1}", sFieldName, sName))
'                End If
'            End If
'        Next
'        clsSql.Append(" FROM ")
'        clsSql.Append(tableName)
'        clsDef.SelectSqlStatement = clsSql.ToString
'        mTypeDefinitions.Add(sName, clsDef)
'    End Sub

'    Public Delegate Sub RowHandlerDelegate(ByVal obj As Object)
'    Public Shared Sub SetRowCompleteHandler(ByVal type As System.Type, ByVal handler As RowHandlerDelegate)
'        Dim clsTD As TypeDefinition = GetTypeDef(type)
'        If clsTD Is Nothing Then Throw New ApplicationException("Type not defined!")
'        clsTD.RowCompleteHandler = handler
'    End Sub

'    Public Delegate Sub SetCustomFieldDelegate(ByVal obj As Object, ByVal value As Object)
'    'Public Delegate Function GetCustomFieldDelegate(ByVal obj As Object) As Object
'    Public Shared Sub AddCustomFieldHandler(ByVal type As System.Type, ByVal fieldName As String, ByVal setHandler As SetCustomFieldDelegate)
'        Dim clsTD As TypeDefinition = GetTypeDef(type)
'        If clsTD Is Nothing Then Throw New ApplicationException("Type not defined!")

'        For i As Integer = 0 To clsTD.ColumnFieldInfos.Count - 1
'            If clsTD.ColumnFieldInfos(i).Name = fieldName Then
'                clsTD.CustomSetHandlers(i) = setHandler
'                Return
'            End If
'        Next
'        Throw New ApplicationException("Field not found!")
'    End Sub

'    Private Shared Function GetTypeDef(ByVal type As System.Type) As TypeDefinition
'        Return mTypeDefinitions.Item(type.Name)
'    End Function

'    Private Shared mTypeDefinitions As New Generic.Dictionary(Of String, TypeDefinition)
'    Private Class TypeDefinition
'        Public Type As System.Type
'        Public SelectSqlStatement As String
'        Public FieldCount As Integer
'        Public TableName As String
'        Public ColumnFieldInfos() As System.Reflection.FieldInfo
'        Public CustomSetHandlers() As SetCustomFieldDelegate
'        Public RowCompleteHandler As RowHandlerDelegate
'    End Class

'    Private Shared Function DRToObject(Of T)(ByVal dr As SqlCeDataReader, ByVal typeDef As TypeDefinition) As T
'        Dim clsType As System.Type = GetType(T)
'        Dim clsRet As T = CType(System.Activator.CreateInstance(GetType(T)), T)
'        For i As Integer = 0 To typeDef.FieldCount - 1
'            Dim oValue As Object = dr.GetValue(i)
'            If oValue IsNot DBNull.Value Then
'                If typeDef.CustomSetHandlers(i) Is Nothing Then
'                    Try
'                        typeDef.ColumnFieldInfos(i).SetValue(clsRet, oValue)
'                    Catch ex As Exception When typeDef.ColumnFieldInfos(i) Is Nothing
'                        Throw New ApplicationException(String.Format("Field with index {0} defined as custom, but to custom field handler was defined!", i))
'                    End Try
'                Else
'                    typeDef.CustomSetHandlers(i).Invoke(clsRet, oValue)
'                End If
'            End If
'        Next
'        If typeDef.RowCompleteHandler IsNot Nothing Then typeDef.RowCompleteHandler.Invoke(clsRet)
'        Return clsRet
'    End Function
'End Class